#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Predesys Server - User Interface - Users management 
@version: 0.2.5
@license: GPL 3.0 (see "license" file)
@author: Jose A. Jimenez
@contact: jajimc@gmail.com"""

import sys
sys.dont_write_bytecode = True
import os
import os.path
DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(os.path.join(DIR, "../core"))
import security
import exceptions
import getpass
import usage
import tools
import users
     
def manageArgs(argc, argv):
    """Manages command line input.
    @param argc: Command line argument count
    @type argc: C{int}
    @param argv: Command line input data
    @type argv: C{list}"""
    if argc == 3 and sys.argv[2] == "list":
        print_user_list()
    elif argc == 4 and sys.argv[2] == "data":
        print_user_data(sys.argv[3])
    elif argc == 3 and sys.argv[2] == "add":
        add_user_interactively()
    elif argc > 3 and sys.argv[2] == "add":
         add_user(sys.argv)
    elif argc == 3 and sys.argv[2] == "mod":
        modify_user_interactively()
    elif argc > 3 and sys.argv[2] == "mod":
        modify_user(sys.argv)
    elif argc == 3 and sys.argv[2] == "changep":
        change_user_password_interactively()
    elif argc > 3 and sys.argv[2] == "changep":
        change_user_password(sys.argv)
    elif argc == 7 and sys.argv[2] == "enable":
        enable_user(sys.argv)
    elif argc == 4 and sys.argv[2] == "del":
        delete_user(sys.argv[3], True)
    elif argc == 5 and sys.argv[2] == "del" and sys.argv[3] == "-f":
        delete_user(sys.argv[4], False)
    else:
        print usage.get_usage()
        
def print_user_list():
    """Prints the ID of every user."""
    userList = users.get_users()
    for userId in userList:
        print userId

def print_user_data(id):
    """Prints all fields of a user.
    @param id: User ID
    @type id: C{str}"""
    userData = users.get_user_data(id)

    print "ID: %s" % userData.get_id()
            
    group = userData.get_group()
    if group != None: groupId = group.get_id()
    else: groupId = "<None>"
    print "GROUP: %s" % groupId
            
    if userData.is_enabled(): enabled = "yes"
    else: enabled = "no"
    print "ENABLED: %s" % enabled
            
    name = userData.get_name()
    if name == None or name == "": name = "<None>"
    print "NAME: %s" % name
            
    email = userData.get_email()
    if email == None or email == "": email = "<None>"
    print "E-MAIL: %s" % email
            
    addresses = userData.get_mac_addresses()
    addressesCount = len(addresses)
    addressesText = ""
    for i in range(0, addressesCount):
        addressesText += addresses[i]
        if i < (addressesCount - 1): addressesText += ", "
    if addressesText == "": addressesText = "<None>"
    print "MAC ADDRESSES: %s" % addressesText
       
def add_user_interactively():
    """Adds a new user prompting for every field in the command line."""
    security.check_root()
    
    ok = False
    while (not ok):
        id = raw_input("ID: ")
        ok = (id != None and id != "")
        if not ok: print "Data not valid, try again"

    groupId = raw_input("Group ID: ")
    if groupId == "": group = None
    else: group = users.UserGroup(groupId, None)
    
    ok = False
    while (not ok):
        enabled = raw_input("Enabled [y/n]: ")
        enabled = enabled.lower()
        ok = (enabled != None and enabled != "" and (enabled == "y" or enabled == "n"))
        if not ok: print "Data not valid, try again"
    enabled = (enabled == "y")
        
    name = raw_input("Name: ")
    if name == "": name = None
    
    email = raw_input("E-mail: ")
    if email == "": email = None
    
    macAddresses = raw_input("MAC addresses (comma separated): ")
    if macAddresses == "":
        macAddresses = None
    else:
        macAddresses = macAddresses.replace(" ", "")
        macAddresses = macAddresses.split(",")
    
    ok = False
    while (not ok):
        password = getpass.getpass("Password: ")
        ok = (password != None and password != "")
        if not ok: print "Data not valid, try again"       
    
    user = users.User(id, group, enabled, name, email, macAddresses)
    users.add_user(user, password)
    print "User added successfully"
    
def add_user(argv):
    """Adds a new user.
    @param argv: Command line input data
    @type argv: C{list}"""
    security.check_root()
    
    id = tools.get_parameter_value(argv, "id")
    if id == None or id == "": raise exceptions.Exception("User ID not valid or not specified")
    
    groupId = tools.get_parameter_value(argv, "gid")
    if groupId == None or groupId == "": group = None
    else: group = users.UserGroup(groupId, None)
    
    enabled = tools.get_parameter_value(argv, "e")
    if enabled == None or enabled == "":
        raise exceptions.Exception("Enabled attribute not valid or not specified")
    else:
        if enabled != "0" and enabled != "1": raise exceptions.Exception("Enabled attribute not valid or not specified")
    enabled = (enabled == "1")
    
    name = tools.get_parameter_value(argv, "n")
    email = tools.get_parameter_value(argv, "em")
    
    macAddresses = tools.get_parameter_value(argv, "mac")
    if macAddresses == "":
        macAddresses = None
    elif macAddresses != None:
        macAddresses = macAddresses.replace(" ", "")
        macAddresses = macAddresses.split(",")
        
    user = users.User(id, group, enabled, name, email, macAddresses)
    users.add_user_no_password(user)   
    print "User added successfully"
    
def modify_user_interactively():
    """Modifies an existing user prompting for every field in the command line."""
    security.check_root()
    
    ok = False
    while (not ok):
        oldId = raw_input("Old ID: ")
        ok = (oldId != None and oldId != "")
        if not ok: print "Data not valid, try again"

    ok = False
    while (not ok):
        newId = raw_input("New ID: ")
        ok = (newId != None and newId != "")
        if not ok: print "Data not valid, try again"
        
    groupId = raw_input("Group ID: ")
    if groupId == "": groupId = None
        
    name = raw_input("Name: ")
    if name == "": name = None
    
    email = raw_input("E-mail: ")
    if email == "": email = None
    
    macAddresses = raw_input("MAC addresses (comma separated): ")
    if macAddresses == "":
        macAddresses = None
    else:
        macAddresses = macAddresses.replace(" ", "")
        macAddresses = macAddresses.split(",")
    
    users.modify_user(oldId, newId, groupId, name, email, macAddresses)
    print "User modified successfully"
    
def modify_user(argv):
    """Modifies an existing user.
    @param argv: Command line input data
    @type argv: C{list}"""
    security.check_root()
    
    oldId = tools.get_parameter_value(argv, "oid")
    if oldId == None or oldId == "": raise exceptions.Exception("User old ID not valid or not specified")
    
    newId = tools.get_parameter_value(argv, "nid")
    if newId == None or newId == "": raise exceptions.Exception("User new ID not valid or not specified")
    
    groupId = tools.get_parameter_value(argv, "gid")
    if groupId == None or groupId == "": group = None
    else: group = users.UserGroup(groupId, None)
    
    name = tools.get_parameter_value(argv, "n")
    email = tools.get_parameter_value(argv, "em")
    
    macAddresses = tools.get_parameter_value(argv, "mac")
    if macAddresses == "":
        macAddresses = None
    elif macAddresses != None:
        macAddresses = macAddresses.replace(" ", "")
        macAddresses = macAddresses.split(",")
        
    users.modify_user(oldId, newId, groupId, name, email, macAddresses)
    print "User modified successfully"
    
def change_user_password_interactively():
    """Modifies the password of an existing user prompting for every field in the command line."""
    security.check_root()
    
    ok = False
    while (not ok):
        userId = raw_input("User ID: ")
        ok = (userId != None and userId != "")
        if not ok: print "Data not valid, try again"
        
    ok = False
    while (not ok):
        newUserPassword = getpass.getpass("New password: ")
        ok = (newUserPassword != None and newUserPassword != "")
        if not ok: print "Data not valid, try again"
        
    users.set_user_password(userId, newUserPassword)
    print "User password changed successfully"
    
def change_user_password(argv):
    """Modifies the password of an existing user.
    @param argv: Command line input data
    @type argv: C{list}"""
    security.check_root()
    
    userId = tools.get_parameter_value(argv, "user")
    if userId == None: raise exceptions.Exception("User ID not valid or not specified")
    
    newUserPassword = tools.get_parameter_value(argv, "passwd")
    if newUserPassword == None: raise exceptions.Exception("New user password not valid or not specified")
    
    users.set_user_password(userId, newUserPassword)
    print "User password changed successfully"
    
def enable_user(argv):
    """Enables/disables an existing user.
    @param argv: Command line input data
    @type argv: C{list}"""
    security.check_root()
    
    userId = tools.get_parameter_value(argv, "id")
    if userId == None: raise exceptions.Exception("User ID not valid or not specified")
    
    enabled = tools.get_parameter_value(argv, "e")
    if enabled == None: raise exceptions.Exception("Enabling value not valid or not specified")
    
    if enabled == "0": enabled = False
    elif enabled == "1": enabled = True
    else: raise exceptions.Exception("Enabling value not valid")
    
    users.enable_user(userId, enabled)
    
    if enabled: print "User enabled successfully"
    else: print "User disabled successfully"
    
def delete_user(id, confirm):
    """Deletes an existing user.
    @param id: User ID
    @type id: C{str}
    @param confirm: Determines if UI must prompt the user a confirmation.
    @type confirm: C{bool}"""
    if confirm:
        ok = False
        while (not ok):
            response = raw_input("Are you sure you want to delete user '%s'? [y/n]: " % id)
            response = response.lower()
            ok = (response != None and response != "" and (response == "y" or response == "n"))
            if not ok: print "Answer not valid"
        if response == "n": 
            exit(0)
            
    users.delete_user(id)
    print "User deleted successfully"
